﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Routing;
using Xoohoo.ActionFilters.Action;
using Xoohoo.ActionFilters.Authorization;
using Xoohoo.Extensions;
using Xoohoo.FilterProviders;
using Xoohoo.FilterProviders.FilterCriterion;
using Xoohoo.Infrastructure.InversionOfControl;
using Xoohoo.Infrastructure;
using Xoohoo.Models;
using Xoohoo.Models.InputModels;
using Xoohoo.Modules.Admin.Controllers;
using Xoohoo.Modules.Admin.Extensions;
using Xoohoo.Modules.Admin.ModelBinders;
using Xoohoo.Modules.Admin.Models;
using Xoohoo.Modules.Admin.Services;
using Xoohoo.Services;

namespace Xoohoo.Modules.Admin
{
    public class AdminModule : Module, IModuleMetaData, IAuthenticationModule
    {
        private readonly Site _site;

        public AdminModule()
        {
            this._site = DependencyInjector.GetService<Site>();
        }

        #region Module Members

        public override string ModuleName
        {
            get { return "Admin"; }
        }

        public override string AuthenticationModuleName
        {
            get { return ModuleName; }
        }

        public override void Initialize()
        {
            DependencyInjector
                .RegisterType<IAdminUserService, AdminUserService>();
        }

        public override void RegisterRoutes()
        {
            string[] controllerNamespaces = new string[] { "Xoohoo.Modules.Admin.Controllers" };
            string adminPath = _site.AdminPath;
            // Admin模块下"管理首页"的路由作特殊处理，
            // 如，一般后台模块的url设置规则是：Admin.模块名称.Controller名称.Action名称。当然，这非强制行要求。
            // 在Admin模块下，省去"模块名称"和"Controller名称"，即：Admin.Action名称

            #region 菜单

            MapRoute("Admin.SubMenu"
                , "{0}/SubMenu".FormatWith(adminPath)
                , new { controller = "Admin", action = "SubMenu" }
                , null
                , controllerNamespaces
                );

            MapRoute("Admin.System.SubMenu"
                , "{0}/System/SubMenu".FormatWith(adminPath)
                , new { controller = "System", action = "SubMenu" }
                , null
                , controllerNamespaces
                );

            #endregion

            #region 管理首页

            MapRoute("Admin.Index"
                , adminPath
                , new { controller = "Admin", action = "Index" }
                , null
                , controllerNamespaces
                );

            MapRoute("Admin.Welcome"
                , "{0}/Welcome".FormatWith(adminPath)
                , new { controller = "Admin", action = "Welcome" }
                , null
                , controllerNamespaces
                );

            MapRoute("Admin.Bulletin"
                , "{0}/Bulletin".FormatWith(adminPath)
                , new { controller = "Admin", action = "Bulletin" }
                , null
                , controllerNamespaces
                );

            MapRoute("Admin.ChangePassword"
                , "{0}/ChangePassword".FormatWith(adminPath)
                , new { controller = "Admin", action = "ChangePassword" }
                , null
                , controllerNamespaces
                );

            MapRoute("Admin.ChangeProfile"
                , "{0}/ChangeProfile".FormatWith(adminPath)
                , new { controller = "Admin", action = "ChangeProfile" }
                , null
                , controllerNamespaces
                );

            #endregion

            #region 系统配置

            MapRoute("Admin.System.SiteConfig"
                , "{0}/System/SiteConfig".FormatWith(adminPath)
                , new { controller = "System", action = "SiteConfig", validateAntiForgeryToken = true }
                , null
                , controllerNamespaces
                );

            MapRoute("Admin.System.Bulletin"
                , "{0}/System/Bulletin".FormatWith(adminPath)
                , new { controller = "System", action = "Bulletin" }
                , null
                , controllerNamespaces
                );

            MapRoute("Admin.System.Restart"
                , "{0}/System/Restart".FormatWith(adminPath)
                , new { controller = "System", action = "Restart" }
                , null
                , controllerNamespaces
                );


            MapRoute("Admin.System.Modules"
                , "{0}/System/Modules".FormatWith(adminPath)
                , new { controller = "System", action = "Modules" }
                , null
                , controllerNamespaces
                );

            MapRoute("Admin.System.ExtractModulePermissions"
                , "{0}/System/ExtractModulePermissions".FormatWith(adminPath)
                , new { controller = "System", action = "ExtractModulePermissions" }
                , null
                , controllerNamespaces
                );

            MapRoute("Admin.System.ClearModulePermissions"
                , "{0}/System/ClearModulePermissions".FormatWith(adminPath)
                , new { controller = "System", action = "ClearModulePermissions" }
                , null
                , controllerNamespaces
                );

            #endregion

            #region 登录注销

            MapRoute("Admin.SignIn"
                , "{0}/SignIn".FormatWith(adminPath)
                , new { controller = "Admin", action = "SignIn" }
                , null
                , controllerNamespaces
                );

            MapRoute("Admin.GetValidateCode"
                , "{0}/GetValidateCode".FormatWith(adminPath)
                , new { controller = "Admin", action = "GetValidateCode" }
                , null
                , controllerNamespaces
                );

            MapRoute("Admin.SignOut"
                , "{0}/SignOut".FormatWith(adminPath)
                , new { controller = "Admin", action = "SignOut" }
                , null
                , controllerNamespaces
                );

            #endregion

        }

        public override void RegisterModelBinders(ModelBinderDictionary modelBinders)
        {
            modelBinders[typeof(SiteInput)] = DependencyInjector.GetService<SiteInputModelBinder>();
            modelBinders[typeof(BulletinInput)] = DependencyInjector.GetService<BulletinInputModelBinder>();

            modelBinders[typeof(UserSignInInput)] = new UserSignInInputModelBinder();
            modelBinders[typeof(UserChangePasswordInput)] = new UserChangePasswordInputModelBinder();
            modelBinders[typeof(UserChangeProfileInput)] = new UserProfileInputModelBinder();
        }

        public override void RegisterFilters(FilterRegistryFilterProvider filterRegistry, GlobalFilterCollection globalFilters)
        {
            #region Filter注册示例
            /*

            //AdminController的SignIn Action
            ControllerActionFilterCriteria criteria1 = new ControllerActionFilterCriteria();
            criteria1.AddMethod<AdminController>(s => s.SignIn());
            filterProvider.Add(new[] { criteria1 }, new Filter(new TimerActionFilter(), FilterScope.First, Int32.MinValue));

            //整个AdminController
            ControllerTypeFilterCriteria criteria2 = new ControllerTypeFilterCriteria();
            criteria2.AddType(typeof(AdminController));
            filterProvider.Add(new[] { criteria2 }, new Filter(new TimerActionFilter(), FilterScope.First, Int32.MinValue));

            //RouteName为Admin.SignIn的Route
            RouteFilterCriteria criteria3 = new RouteFilterCriteria(routeTable);
            criteria3.AddRoute("Admin.SignIn");
            filterProvider.Add(new[] { criteria3 }, new Filter(new TimerActionFilter(), FilterScope.First, Int32.MinValue));

            //RouteValue中包含为testKey，且值为testValue
            RouteValueFilterCriteria criteria4 = new RouteValueFilterCriteria("testKey", "testValue");
            filterProvider.Add(new[] { criteria4 }, new Filter(new TimerActionFilter(), FilterScope.First, Int32.MinValue));
            
            //RouteValue中包含为area，且值为admin
            DataTokenFilterCriteria criteria5 = new DataTokenFilterCriteria("area", "admin");
            filterProvider.Add(new[] { criteria5 }, new Filter(new TimerActionFilter(), FilterScope.First, Int32.MinValue));
            
            
            //12大组合权限判断
            //Controller -> AuthorizationFilter
            //Controller -> AdvancedAuthorizationFilter
            //Controller -> RouteAuthorizationFilter
            //Action -> AuthorizationFilter
            //Action -> AdvancedAuthorizationFilter
            //Action -> RouteAuthorizationFilter
            //Route -> AuthorizationFilter
            //Route -> AdvancedAuthorizationFilter
            //Route -> RouteAuthorizationFilter
            //RouteValue -> AuthorizationFilter
            //RouteValue -> AdvancedAuthorizationFilter
            //RouteValue -> RouteAuthorizationFilter
            
            */
            #endregion

            #region 页面执行计时器

            // TimerActionFilter 页面执行时间,为了使计时更准确，使其尽量排在其他Filter之前
            ControllerActionFilterCriteria timerCriteria = new ControllerActionFilterCriteria();
            timerCriteria.AddMethod<SystemController>(s => s.Modules());
            timerCriteria.AddMethod<SystemController>(s => s.SiteConfig());
            filterRegistry.Add(new[] { timerCriteria }, new Filter(new TimerActionFilter(), FilterScope.First, Int32.MinValue));

            #endregion

            #region 菜单权限

            ControllerActionFilterCriteria adminSubMenuCriteria = new ControllerActionFilterCriteria();
            adminSubMenuCriteria.AddMethod<AdminController>(s => s.SubMenu());
            filterRegistry.Add(new[] { adminSubMenuCriteria }, new AdvancedAuthorizationFilter(DependencyInjector, user => user.HasPermission("后台管理")));

            ControllerActionFilterCriteria systemSubMenuCriteria = new ControllerActionFilterCriteria();
            systemSubMenuCriteria.AddMethod<SystemController>(s => s.SubMenu());
            filterRegistry.Add(new[] { systemSubMenuCriteria }, new AdvancedAuthorizationFilter(DependencyInjector, user => user.HasPermission("系统管理")));

            #endregion

            #region 管理首页权限

            ControllerActionFilterCriteria adminIndexCriteria = new ControllerActionFilterCriteria();
            adminIndexCriteria.AddMethod<AdminController>(s => s.Index());
            adminIndexCriteria.AddMethod<AdminController>(s => s.Welcome());
            adminIndexCriteria.AddMethod<AdminController>(s => s.Bulletin());
            filterRegistry.Add(new[] { adminIndexCriteria }, new AdvancedAuthorizationFilter(DependencyInjector, user => user.HasPermission("后台管理")));

            ControllerActionFilterCriteria changeProfileCriteria = new ControllerActionFilterCriteria();
            changeProfileCriteria.AddMethod<AdminController>(s => s.ChangeProfile());
            changeProfileCriteria.AddMethod<AdminController>(s => s.ChangeProfile(null));
            filterRegistry.Add(new[] { changeProfileCriteria }, new AdvancedAuthorizationFilter(DependencyInjector, user => user.HasPermission("后台修改资料")));

            ControllerActionFilterCriteria changePasswordCriteria = new ControllerActionFilterCriteria();
            changePasswordCriteria.AddMethod<AdminController>(s => s.ChangePassword());
            changePasswordCriteria.AddMethod<AdminController>(s => s.ChangePassword(null));
            filterRegistry.Add(new[] { changePasswordCriteria }, new AdvancedAuthorizationFilter(DependencyInjector, user => user.HasPermission("后台修改密码")));

            /*
             * 
            ControllerFilterCriteria controllerFilterCriteria = new ControllerFilterCriteria();
            controllerFilterCriteria.AddType(typeof(AdminController));
            filterRegistry.Add(new[] { controllerFilterCriteria }, new AdvancedAuthorizationFilter(container, user => user.HasPermission("后台修改密码111"));

            RouteFilterCriteria routeFilterCriteria = new RouteFilterCriteria(routeTable);
            routeFilterCriteria.AddRoute("Admin.System.SubMenu111");
            filterRegistry.Add(new[] { routeFilterCriteria }, new RoutePermissionAuthorizationFilter(container, "后台修改密码111"));

             * 
            */

            #endregion

            #region 系统管理权限

            ControllerActionFilterCriteria siteConfigCriteria = new ControllerActionFilterCriteria();
            siteConfigCriteria.AddMethod<SystemController>(s => s.SiteConfig());
            siteConfigCriteria.AddMethod<SystemController>(s => s.SiteConfig(null));
            filterRegistry.Add(new[] { siteConfigCriteria }, new AdvancedAuthorizationFilter(DependencyInjector, user => user.HasPermission("系统配置")));

            ControllerActionFilterCriteria bulletinCriteria = new ControllerActionFilterCriteria();
            bulletinCriteria.AddMethod<SystemController>(s => s.Bulletin());
            bulletinCriteria.AddMethod<SystemController>(s => s.Bulletin(null));
            filterRegistry.Add(new[] { bulletinCriteria }, new AdvancedAuthorizationFilter(DependencyInjector, user => user.HasPermission("系统公告")));

            ControllerActionFilterCriteria restartCriteria = new ControllerActionFilterCriteria();
            restartCriteria.AddMethod<SystemController>(s => s.Restart());
            filterRegistry.Add(new[] { restartCriteria }, new AdvancedAuthorizationFilter(DependencyInjector, user => user.HasPermission("重启系统")));

            ControllerActionFilterCriteria modulesCriteria = new ControllerActionFilterCriteria();
            modulesCriteria.AddMethod<SystemController>(s => s.Modules());
            filterRegistry.Add(new[] { modulesCriteria }, new AdvancedAuthorizationFilter(DependencyInjector, user => user.HasPermission("模块信息")));

            ControllerActionFilterCriteria modulePermissionsCriteria = new ControllerActionFilterCriteria();
            modulePermissionsCriteria.AddMethod<SystemController>(s => s.ExtractModulePermissions());
            filterRegistry.Add(new[] { modulePermissionsCriteria }, new AdvancedAuthorizationFilter(DependencyInjector, user => user.HasPermission("提取权限")));

            ControllerActionFilterCriteria clearModulePermissionsCriteria = new ControllerActionFilterCriteria();
            clearModulePermissionsCriteria.AddMethod<SystemController>(s => s.ClearModulePermissions());
            filterRegistry.Add(new[] { clearModulePermissionsCriteria }, new AdvancedAuthorizationFilter(DependencyInjector, user => user.HasPermission("清理权限")));

            #endregion
        }

        #endregion

        #region IXoohooModuleMetaData Members

        public List<ModuleMenuItem> GetModuleMenus()
        {
            return new List<ModuleMenuItem>
            {
                new ModuleMenuItem
                {
                    Title = "管理首页",
                    SubMenuRouteName = "Admin.SubMenu",
                    ContentRouteName = "Admin.Welcome",
                    Permission = "后台管理"
                },
                new ModuleMenuItem
                {
                    Title = "系统管理",
                    SubMenuRouteName = "Admin.System.SubMenu",
                    ContentRouteName = "Admin.System.SiteConfig",
                    Permission = "系统管理"
                }
            };
        }

        public List<PermissionInput> GetModulePermissions()
        {
            var permissions = new List<PermissionInput>()
            {
               new PermissionInput(){ PermissionID = new Guid("{303EC418-A517-4220-9B08-206FFF81DE2A}"), PermissionName="后台管理", ModuleName= this.ModuleName}
              ,new PermissionInput(){ PermissionID = new Guid("{2E89D5F5-B949-433b-A166-B1C6211A9302}"), ParentID = new Guid("{303EC418-A517-4220-9B08-206FFF81DE2A}"),PermissionName="后台修改资料", ModuleName= this.ModuleName}
              ,new PermissionInput(){ PermissionID = new Guid("{B80B1C90-3F1E-4412-9836-46A86DCF9FC2}"), ParentID = new Guid("{303EC418-A517-4220-9B08-206FFF81DE2A}"),PermissionName="后台修改密码", ModuleName= this.ModuleName}
              ,new PermissionInput(){ PermissionID = new Guid("{10B03A60-6E59-4cc7-8AB5-2CEC1F0695AE}"), PermissionName="系统管理", ModuleName= this.ModuleName}
              ,new PermissionInput(){ PermissionID = new Guid("{2CC40EA3-E24D-4b1d-BD03-4FC5B4E30EE1}"), ParentID = new Guid("{10B03A60-6E59-4cc7-8AB5-2CEC1F0695AE}"),PermissionName="系统信息", ModuleName= this.ModuleName}
              ,new PermissionInput(){ PermissionID = new Guid("{F65ACCB5-6BCF-41fa-8614-F3C7EBBFC338}"), ParentID = new Guid("{10B03A60-6E59-4cc7-8AB5-2CEC1F0695AE}"),PermissionName="系统配置", ModuleName= this.ModuleName}
              ,new PermissionInput(){ PermissionID = new Guid("{23309B5D-5745-4153-8B8D-F00BBCE54EF5}"), ParentID = new Guid("{10B03A60-6E59-4cc7-8AB5-2CEC1F0695AE}"),PermissionName="系统公告", ModuleName= this.ModuleName}
              ,new PermissionInput(){ PermissionID = new Guid("{957DFBCC-9139-4247-842C-F9A794BC4BC7}"), ParentID = new Guid("{10B03A60-6E59-4cc7-8AB5-2CEC1F0695AE}"),PermissionName="重启系统", ModuleName= this.ModuleName}
              ,new PermissionInput(){ PermissionID = new Guid("{39587146-885C-414c-98A7-9B157C83C374}"), PermissionName="模块管理", ModuleName= this.ModuleName}
              ,new PermissionInput(){ PermissionID = new Guid("{7ACE2FCC-535D-40a6-BA2B-A2D368981ED7}"), ParentID = new Guid("{39587146-885C-414c-98A7-9B157C83C374}"),PermissionName="模块信息", ModuleName= this.ModuleName}
              ,new PermissionInput(){ PermissionID = new Guid("{DB49EA0F-B5AD-44c9-B41C-DB6540C52CC5}"), ParentID = new Guid("{39587146-885C-414c-98A7-9B157C83C374}"),PermissionName="提取权限", ModuleName= this.ModuleName}
              ,new PermissionInput(){ PermissionID = new Guid("{9A1BAAFF-2246-4d1f-B3A2-52C47EF83DAF}"), ParentID = new Guid("{39587146-885C-414c-98A7-9B157C83C374}"),PermissionName="清理权限", ModuleName= this.ModuleName}
 
            };

            return permissions;
        }

        #endregion

        #region IXoohooAuthenticationModule Members

        public IUser GetUser(RequestContext context)
        {
            if (context.HttpContext.User.Identity.IsAuthenticated)
            {
                IUserService userService = DependencyInjector.GetService<IUserService>();
                if (userService != null)
                {
                    string[] nameWithModule = context.HttpContext.User.Identity.Name.Split('|');
                    if (nameWithModule.Length == 2)
                    {
                        if (nameWithModule[0] == this.ModuleName)
                            return userService.GetItem(nameWithModule[1], UserStatus.Normal);
                    }
                }
            }
            return new UserAnonymous();
        }

        public string GetRegistrationUrl(RequestContext context)
        {
            return null;
        }

        public string GetSignInUrl(RequestContext context)
        {
            UrlHelper urlHelper = new UrlHelper(context, DependencyInjector.GetService<RouteCollection>());

            return urlHelper.AdminSignIn();
        }

        public string GetSignOutUrl(RequestContext context)
        {
            UrlHelper urlHelper = new UrlHelper(context, DependencyInjector.GetService<RouteCollection>());

            return urlHelper.AdminSignOut();
        }

        #endregion

    }
}
